2.2 No.2:不必要にネストしたコード
間違い
ネストが増えていくと読みやすさが失われていく
下記は実装として正しい関数だが、ネストが非常に増えてしまっていて認知負荷が高まっている
code:go
func join1(s1, s2 string, max int) (string, error) {
if s1 == "" {
return "", errors.New("s1 is empty")
} else {
if s2 == "" {
return "", errors.New("s2 is empty")
} else {
concat, err := concatenate(s1, s2)
if err != nil {
return "", err
} else {
if len(concat) > max {
return concat:max, nil
} else {
return concat, nil
}
}
}
}
}
func concatenate(s1, s2 string) (string, error) {
return "", nil
}
解決策
happy pathを左側に揃え、1列目を下まで目を通せば期待する実行の流れをすぐに確認できるようにするとコードが読みやすくなる
code:go
func join2(s1, s2 string, max int) (string, error) {
if s1 == "" {
return "", errors.New("s1 is empty")
}
if s2 == "" {
return "", errors.New("s2 is empty")
}
concat, err := concatenate(s1, s2)
if err != nil {
return "", err
}
if len(concat) > max {
return concat:max, nil
}
return concat, nil
}
func concatenate(s1, s2 string) (string, error) {
return "", nil
}
ifブロックがリターンする時は、どのような場合でもelseブロックを省略すべき
code:go
// Bad
if foo() {
return true
} else {
// ...
}
// Good
if foo() {
return true
}
// ...
ロジックを非ハッピーパスで追って改善する
code:go
// 非ハッピーパス
if s1 != "" {
// ...
} else {
return "", errors.New("empty string")
}
// ハッピーパス
if s1 == "" {
return "", errors.New("empty string")
}